/**
 * @file gpio_lib.h
 * @brief 通用GPIO操作库头文件
 * 
 * 提供GPIO操作的通用函数声明，以提高代码复用性和移植性。
 * 
 * @author 伞控无人机项目组
 * @date 2023
 */

#ifndef GPIO_LIB_H
#define GPIO_LIB_H

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "log_utils.h"

// GPIO方向定义
typedef enum {
    GPIO_DIR_INPUT = 0,  // 输入模式
    GPIO_DIR_OUTPUT = 1  // 输出模式
} gpio_direction_t;

// GPIO边沿触发定义（仅对输入有效）
typedef enum {
    GPIO_EDGE_NONE = 0,   // 不触发
    GPIO_EDGE_RISING = 1, // 上升沿触发
    GPIO_EDGE_FALLING = 2,// 下降沿触发
    GPIO_EDGE_BOTH = 3    // 双边沿触发
} gpio_edge_t;

// GPIO值定义
typedef enum {
    GPIO_VALUE_LOW = 0,  // 低电平
    GPIO_VALUE_HIGH = 1  // 高电平
} gpio_value_t;

// GPIO句柄定义
typedef struct {
    int gpio_num;              // GPIO编号
    char gpio_name[32];        // GPIO名称
    int is_initialized;        // 是否已初始化
} gpio_handle_t;

/**
 * @brief 将GPIO引脚名转换为GPIO编号
 * 
 * @param gpio_pin GPIO引脚名，格式为"X_YZ_d"，例如"4_A2_d"
 * @return int 成功返回GPIO编号，失败返回-1
 */
int gpio_name_to_number(const char *gpio_pin);

/**
 * @brief 保存GPIO配置到文件
 * 
 * 将当前所有已初始化的GPIO配置保存到文件中，以便在程序重启后恢复
 * 
 * @return int 成功返回0，失败返回负数
 */
int gpio_save_config(void);

/**
 * @brief 从文件加载GPIO配置
 * 
 * 从配置文件中加载并初始化所有GPIO
 * 
 * @return int 成功返回0，失败返回负数
 */
int gpio_load_config(void);

/**
 * @brief 初始化GPIO
 * 
 * @param handle GPIO句柄指针，用于保存初始化结果
 * @param gpio_pin GPIO引脚名，格式为"X_YZ_d"，例如"4_A2_d"
 * @param direction GPIO方向，输入或输出
 * @param edge 边沿触发方式（仅对输入有效）
 * @return int 成功返回0，失败返回负数
 */
int gpio_init(gpio_handle_t *handle, const char *gpio_pin, gpio_direction_t direction, gpio_edge_t edge);

/**
 * @brief 读取GPIO状态
 * 
 * @param handle 已初始化的GPIO句柄
 * @return int 成功返回GPIO状态(0或1)，失败返回负数
 */
int gpio_read(const gpio_handle_t *handle);

/**
 * @brief 设置GPIO状态（仅对输出模式有效）
 * 
 * @param handle 已初始化的GPIO句柄
 * @param value 要设置的值，0或1
 * @return int 成功返回0，失败返回负数
 */
int gpio_write(const gpio_handle_t *handle, gpio_value_t value);

/**
 * @brief 切换GPIO输出状态（仅对输出模式有效）
 * 
 * @param handle 已初始化的GPIO句柄
 * @return int 成功返回0，失败返回负数
 */
int gpio_toggle(const gpio_handle_t *handle);

/**
 * @brief 释放GPIO资源
 * 
 * @param handle 要释放的GPIO句柄
 */
void gpio_cleanup(gpio_handle_t *handle);

/**
 * @brief 注册GPIO清理函数
 * 
 * 注册信号处理函数，确保在程序异常退出时释放GPIO资源。
 * 该函数应当在main函数开始时调用一次，而不是在每个使用GPIO的线程中调用。
 */
void gpio_register_cleanup_handlers(void);

/**
 * @brief 手动清理所有GPIO资源
 * 
 * 提供给外部调用的GPIO清理接口，可以在程序正常退出时手动调用
 */
void gpio_cleanup_all(void);

#endif // GPIO_LIB_H 